//
//  StrokeList.m
//  Playground
//
//  Created by Basuke on 08/03/23.
//  Copyright 2008 Basuke's. All rights reserved.
//

#import "StrokeList.h"


@implementation StrokeList

- (id)init {
	if (self = [super init]) {
		strokes = [[NSMutableArray arrayWithCapacity:100] retain];
		current = [[NSMutableDictionary dictionaryWithCapacity:3] retain];
	}
	
	return self;
}

- (void)dealloc {
	[strokes release];
	[current release];
	
	[super dealloc];
}

- (void)strokeAllPath:(CGContextRef)context {
	for (Stroke *stroke in strokes) {
		[stroke strokePath:context];
	}
	
	for (id key in current) {
		[[current objectForKey:key] strokePath:context];
	}
}

- (CGRect)bounds {
	CGRect	bounds = CGRectNull;
	
	for (Stroke *stroke in strokes) {
		CGRect r = stroke.bounds;
		if (CGRectIsNull(bounds)) {
			bounds = r;
		} else {
			bounds = CGRectUnion(bounds, r);
		}
	}
	
	return bounds;
}

- (UIImage *)renderAsImage {
	CGContextRef		_cgContext;
	CGLayerRef			_cgLayer;
	CGRect				allBounds;
	CGContextRef		context;
	CGColorSpaceRef		colorSpace;
	//Create the offscreen context that contains our finger-painted image i.e. "painting context"
	colorSpace = CGColorSpaceCreateDeviceRGB();
	_cgContext = CGBitmapContextCreate(NULL, allBounds.size.width, allBounds.size.height, 8, 4 * allBounds.size.width, colorSpace, kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(colorSpace);
	if(_cgContext == NULL) return nil;
	
	//Create another offscreen context to contain the current finger stroke i.e. "stroke context" (we need to use a separate context so that blending of the current stroke over the painting context is done right)
	_cgLayer = CGLayerCreateWithContext(_cgContext, allBounds.size, NULL);
	context = CGLayerGetContext(_cgLayer);
	
 {
	 CGContextClearRect(_cgContext, [self bounds]);
	 
	 //Merge the content of the stroke context with the painting context
	 CGContextDrawLayerInRect(_cgContext, [self bounds], _cgLayer);
	 
	 //Clear the stroke context
	 CGContextClearRect(CGLayerGetContext(_cgLayer), [self bounds]);
	 
	 CGRect				bounds = [self bounds];
	 CGImageRef			image;
	 
	 //Copy the contents of the painting context to the view's context
	 image = CGBitmapContextCreateImage(_cgContext);
	 CGContextDrawImage(context, bounds, image);
	 CGImageRelease(image);
	 
	 //Blend on top the contents of the stroke context
	 CGContextDrawLayerInRect(context, bounds, _cgLayer);
 }
	
	CGLayerRelease(_cgLayer);
	CGContextRelease(_cgContext);
	
	return nil;
}

- (void)clear {
	[strokes removeAllObjects];
	[current removeAllObjects];
}

- (BOOL)isRecording:(NSString *)key {
	return ([current objectForKey:key] != nil);
}

- (BOOL)isRecording {
	return ([current count] > 0);
}

- (void)recordPoint:(CGPoint)point forKey:(NSString *)key {
	Stroke *stroke = [current objectForKey:key];
	if (stroke == nil) {
		stroke = [[[Stroke alloc] init] autorelease];
		[current setObject:stroke forKey:key];
	}
	
	[stroke addPoint:point];
}

- (void)commitRecording {
	for (id key in current) {
		Stroke *stroke = [current objectForKey:key];
		[strokes addObject:stroke];
	}
	[current removeAllObjects];
}

- (void)rollbackRecordingForKey:(NSString *)key {
	Stroke *stroke = [current objectForKey:key];
	if (stroke != nil) {
		[current removeObjectForKey:key];
	}
}

- (void)rollbackRecording {
	[current removeAllObjects];
}

@end

